package com.cskaoyan.javase.oop1._1basic;

/**
 * 案例:
 * 创建学生对象，然后使用访问学生对象的属性，使用学生对象的行为。
 *
 * 对象与类的基本语法
 * 定义类和根据类这个模板来创建对象,以及使用对象
 *
 * 类是创建对象的模板,所以为了使用学生对象,需要先创建学生类
 * 学生类的定义,要分两个步骤:
 *      1.类本身结构的定义
 *      2.类体中内容的定义
 *
 * 类本身结构的定义:
 * 语法:
 * [类修饰符列表] class 类名{
 *   // 类体
 * }
 * 解释:
 *      1.类的修饰符列表,可用的修饰符不多,但是现在没有学习,随着学习进度会慢慢学习.
 *          这里我们就仅知道类的修饰符可以是两种:
 *              a.public class 必须和文件名保持一致,一个java文件下最多只有一个
 *              b.非public class 不受限制,一个java文件下可以有多个,而且名字没有要求
 *              这些class在同一个java文件下都是同包的关系.
 *
 *      2.class是一个关键字,表示定义了一个类
 *      3.类名,遵循"大驼峰式"的命名规范,最好"见名知意".而且类一般是抽取对象的共性,描述个体的共性
 *          所以一般使用名字
 *      4.类体的大括号不是代码块,也不是定义局部变量的局部位置.
 *
 *      约定:
 *          正常的开发中,一个java文件下大多都只有一个public class 很少有非public class
 *          但是为了上课方便,我们都会定义非public class 方便看代码
 *              然后在一个public class当中测试非public class 作为一个测试类
 *
 *      强调:
 *          方法是不能嵌套定义的,方法的内部不能再定义一个方法
 *          但是类可以嵌套定义
 *          把一个类定义在另一个类的内部,称之为"内部类"
 *          这种语法虽然允许,但是你没学过,你不懂,定义内部类后就会导致很多语法问题
 *          所以:
 *              做作业的时候一定要搞清楚类体的大括号在哪里
 *              不要嵌套定义类,定义内部类
 *
 * 类体中内容的定义:
 * 既然类是创建对象的"模板"，那么就应该能够描述一种类别的全体对象，
 * 某个对象具有属性和行为
 * 所以：
 * 我们抽象对象全体的共有"属性"，在类中用"成员变量(member variable)"来描述对象共性的属性。
 *      何为成员变量: 指的是定义在类的成员位置的变量.
 *          成员位置: 类体中,方法体,代码块等局部位置之外的位置都是成员位置!
 *      成员变量定义的语法:
 *          [修饰符列表] 数据类型 成员变量名;
 *          注:
 *              成员变量的修饰符列表我们没有学习
 *              这里先不管它,默认是空即可.
 *      何为局部变量: 指的是定义在方法体,代码块,方法的形参等局部位置的变量.
 *
 * 我们抽象对象全体的共有"行为"，在类中用"成员方法"来描述对象共性的行为。
 *      何为成员方法?
 *      定义在成员位置的,没有static修饰的方法就是成员方法.
 *      语法:
 *      [修饰符列表] 返回值类型 方法名(形参列表){
 *          // 方法体
 *      }
 *      注:
 *          修饰符列表可以有很多,但成员方法不能用static修饰,用了static修饰后就不是成员方法了.
 *          现在我们默认修饰符列表是"public"
 *
 * 类的(普通)成员:我们将成员变量和成员方法合起来统称为类的（普通）成员。
 *
 * 以上将一个类就定义完成了.
 * 以上,无论是成员变量,还是成员方法,都是属于对象的
 * 必须创建类的对象(或者本身就有对象)
 * 才能够去访问成员变量和成员方法.
 *
 * 创建对象的语法:
 * 创建类的对象一般需要在方法中进行，
 * 在确定能够创建对象的地方，可以使用以下语法创建对象：
 *      类名 对象名 = new 类名();
 *  这个语法，我们并不陌生，在Scanner键盘录入的时候，已经见过了，现在做如下解释：
 *
 *      1.类名表示创建是何种对象，对象的类型是什么。
 *      2.对象名和之前讲的数组名是一个概念，都是引用数据类型的引用。
 *      作为一个变量名，对象名遵循小驼峰式的命名规范。
 *      对象名是一个引用,是一个局部变量,存储在方法的栈帧中.
 *      3.new关键字表示在堆上开辟空间创建对象，注意代码中的new关键字表示一定会在堆上创建一个独立的对象。
 *
 *     4.栈帧中的引用通过存储堆上对象的地址和堆上的对象产生联系.对象是实质,但是我们只能通过引用间接访问对象.
 *
 * ------------------
 * 对象创建完毕后,就可以使用对象名(引用)去访问对象了,去操作对象了.
 *     比如访问对象的成员变量,可以用
 *          "对象名.成员变量名"
 *          同时可以访问,也可以赋值
 *          成员变量是属于对象的,它直接存储在对象当中
 *          相当于数组对象中的元素
 *          在JVM创建这个类的对象的过程中
 *          JVM会给对象中的成员变量默认初始化
 *          具有默认值(默认值和数组对象一样)
 *
 *     比如调用对象的成员方法,可以用
 *          "对象名.成员方法名"
 *          具体方法的调用和之前public static方法是一样的,不过是调用方式不同.
 *
 *
 *     以上使用对象的引用去访问对象的成员变量和成员方法
 *     要注意,不同的对象,成员变量和成员方法是相互隔离的,是不会互相影响的的.
 *
 *     实际上,一个类的,不同对象,即便是调用同名的成员方法,它的行为也可能是不同的.
 *     这是因为在成员方法中可以访问对象中的成员变量,不同的对象成员变量的取值不同,于是它们成员方法的具体行为也可能有差异.
 *
 *     总之成员变量成员方法属于对象,不同对象的成员变量取值和成员方法的具体调用结果,可能是不同的.
 *
 *
 *---------------------------------------
 * 最后我们来看一下,直接输出对象名(引用)
 * 会得到一个字符串:
 * com.cskaoyan.javase.oop1._1basic.Student@1540e19d
 * 是:
 * 全限定类名 + "@" + 十六进制的地址值
 * 和直接输出数组名一样
 * 注:
 *      默认情况下,输出对象名是打印地址值
 *      但这个字符串输出是可以被修改的
 *      可以不打印全限定类名和地址值
 *
 *
 *
 *
 * @since 14:41
 * @author wuguidong@cskaoyan.onaliyun.com
 */
// 测试类
public class Demo {

    // 成员位置
    public static void main(String[] args) {
        // 这里是可以创建Student对象的
        // 创建Student对象
        Student s = new Student();
        System.out.println(s.name);
        System.out.println(s.score);
        System.out.println(s.stuId);
        s.name = "张三";
        System.out.println(s.name);

        s.study();
        s.sleep();
        s.eat();

        Student s2 = new Student();
        s2.name = "李四";
        System.out.println(s2.name);
        s2.sleep();

        System.out.println("-------------------");
        System.out.println(s);
        System.out.println(s2);
    }

    // 成员位置

    // static修饰的方法不是成员方法
    public static void test() {
    }
}

// 定义学生类
class Student {
    /*
        学生类抽取全体学生对象的共性属性特征
        用成员变量描述
        学生对象的共有属性:
            姓名
            学号
            成绩
            ...
     */
    String name;
    int stuId;
    double score;

    /*
        学生类抽取全体学生对象的共性行为特征
        用成员方法描述
        学生对象的共有行为有:
            学习
            吃饭
            睡觉
            ...
     */
    public void study() {
        System.out.println("好好学习,天天向上!");
    }

    public void eat() {
        System.out.println("吃饭是为了更好的学习!");
    }

    public void sleep() {
        System.out.println(name + "你怎么睡得着的?");
    }


}